/**
 * 下面代码执行顺序是2 3 1
 * 宏任务与微任务，先执行所有宏任务，确认没有微任务就再次执行宏任务
 * 有微任务就执行完微任务再执行宏任务，周而复始
 */
// // 定时器会放入宏任务
// setTimeout(() => {
//     console.log("1");
// }, 1000);

// // 同步任务会直接执行
// console.log("2");

// // Promise也是同步任务会直接执行，then方法是微任务
// new Promise((resolve,reject)=>{
//     reject("no");
//     console.log("3");
// }).then(value=>{
//     console.log(value);
// },reason=>{
//     console.log(reason);
// });


/**
 * then也是个Promise
 * then后面加then，如果前面的then不返回一个Promise，则后面的then默认为成功，执行成功的方法
 * 后面的then会接受前面的then最后的返回值（如以下代码）
 * then返回新的Promise后，旧的Promise的状态会变成新的Promise的状态
 * catch:处理所有的错误,参数接受reject的参数
 * finally:无论是resolve还是reject，finally一定会执行，并且方法是微任务，不会等所有方法执行完后再执行
 */
// new Promise((resolve, reject) => {
//     resolve("第一");
// }).then(
//     value => {
//         return new Promise((resolve, reject) => {
//             resolve("第二");
//         }).then(
//             value => {
//                 return new Promise((resolve, reject) => {
//                     resolve("第三");
//                 }).then(
//                     value => {
//                         return new Promise((resolve, reject) => {
//                             resolve("第四");
//                         })
//                     }
//                 )
//             }
//         )
//     }
// ).then(
//     value => {
//         console.log(`${value}成功`);
//     }
// ).catch(error => {
//     //处理所有的错误,参数接受reject的参数
//     console.log(error);
//     throw new Error("错误");
// }).finally(value => {
//     //无论是resolve还是reject，finally一定会执行，
//     // 并且方法是微任务，不会等所有方法执行完后再执行
//     console.log("所有东西执行完毕");
// })



/**
 * 这个封装的用途在多段动画上，比如向左执行一段距离之后再向下执行一段距离
 * 每个then可以执行一段动画
 */
// function interval(time = 1000, callback) {
//     return new Promise(resolve => {
//         let id = setInterval(() => {
//             callback(id, resolve)
//         }, time);
//     })
// }

// let num = 0;
// interval(10, (id, resolve) => {
//     num++;
//     console.log(num);
//     if (num == 5) {
//         clearInterval(id);
//         resolve();
//     }
// }).then(value => {
//     console.log("所有东西执行完毕");
// })
// console.log("object");

//直接返回一个成功的Promise
// let resolve = Promise.resolve('成功');
//直接返回一个失败的Promise
// let reject = Promise.reject('失败');

//接受所有的Promise，但是有其中一个失败就触发catch
// let all = Promise.all([resolve, reject]);
// all.then(value => {
//     console.log(value);
// }).catch(value => {
//     console.log(value);
// });

//接受所有的Promise，但是不关心是否成功
// let allSettled = Promise.allSettled([resolve, reject]);
// allSettled.then(value => {
//     console.log(value);
// });
// //接受多个的Promise，最终返回执行最快的那个Promise
// let race = Promise.race([resolve, reject])

//如果class里有then方法，实例化函数的时候会自动把then方法当成一个Promise
// class Test {
//     constructor(name) {
//         this.name = name;
//     }
//     //如果class里有then方法，实例化函数的时候会自动把then方法当成一个Promise
//     then(resolve) {
//         resolve(this.name);
//     }
// }
// async function user() {
//     let name = await new Test("zwz");
//     console.log(name);
// }
// user();

// function say() {
//     return new Promise(function (resolve, reject) {
//         setTimeout(function () {
//             let age = 26
//             resolve(`hello, joel。今年我 ${age} 岁`);
//         }, 1000);
//     });
// }
// console.log("object");
// // 这里相当于定义了一个new Promise()是同步进行的
// async function test() {
//     // 如果定义了一个await，那会执行异步操作，暂停函数，相当于把函数变成微任务
//     // await相当于定义了一个then链，只有上一个await执行完才能执行下一个await
//     // 并且如果await后面跟着一个Promise，那只能等这个Promise执行完才能执行后面的代码
//     let user1 = await new Promise((resolve, reject) => {
//         setTimeout(() => {
//             let age = 26
//             reject(`hello, joel。今年我 ${age} 岁`);
//         }, 1000);
//     });
//     // 如果上一个await抛出错误，只能先把这个错误处理后才能执行下面的代码
//     // 可以使用内部try catch 或者外部catch
//     let user = await say();
//     console.log(user);
//     console.log("123456");

// }
// test();
// console.log("1");


// Promise封装AJAX
// 作用：解决回调地狱，AJAX本身是异步的，不需要担心阻塞问题，所以Promise封装就是为了解决代码回调问题
function ajax(url) {
    return new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest();
        xhr.open("GET", url);
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    resolve(xhr.response);
                } else {
                    reject("error");
                }
            }
        }
        xhr.send();
    });
}